import { TranslationEditing } from "@czmSrc/EditingSystem/base";
import { ESCesiumViewer } from "@czmSrc/ESCesiumViewer";
import { CzmES3DTileset, localPositionsToPositions, positionsToLocalPositions } from "@czmSrc/index";
import { ES3DTileset, ESJEditingMode, ESJVector3DArray, ESSceneObject, getMinMaxCorner } from "earthsdk3";
import { bind, nextAnimateFrame } from "xbsj-base"
import { BaseEditingWrapper } from "./BaseEditingWrapper";
export class TranslationEditingWrapper extends BaseEditingWrapper {
    static readonly type = this.registerEditing("ESCesiumViewer", ESJEditingMode.Translation, this);
    constructor(sceneObject: ESSceneObject | ESSceneObject[], czmViewer: ESCesiumViewer) {
        super(Array.isArray(sceneObject) ? sceneObject[0] : sceneObject, czmViewer, true);
        const translationEditing = this.currentEditing = this.ad(new TranslationEditing(czmViewer));
        this.ad(translationEditing.enabledChanged.don((newVal) => {
            !newVal && this.ad(nextAnimateFrame(() => {
                this.destroy();
            }));
        }));
        do {
            if (Array.isArray(sceneObject)) {
                const tempArr: ESJVector3DArray = [];
                for (let i = 0; i < sceneObject.length; i++) {
                    const pp = sceneObject[i];
                    if (Reflect.has(pp, 'position')) {
                        //@ts-ignore
                        tempArr.push(pp.position);
                    } else {
                        //@ts-ignore
                        pp.points && tempArr.push(...pp.points);
                    }
                }
                translationEditing.position = getMinMaxCorner(tempArr).center;
                this.ad(translationEditing.positionChanged.disposableOn((v, ov) => {
                    if (!v || !ov) return;
                    // 通过局部坐标计算平移量
                    var d = positionsToLocalPositions({ originPosition: ov }, [v])[0][0];
                    sceneObject.forEach(item => {
                        if (Reflect.has(item, 'position')) {
                            //@ts-ignore
                            // 转为局部坐标后，增加平移量，再转为世界坐标
                            const tempPosition = positionsToLocalPositions({ originPosition: ov }, [item.position])[0][0];
                            //@ts-ignore
                            item.position = localPositionsToPositions({ originPosition: ov }, [[tempPosition[0] + d[0], tempPosition[1] + d[1], tempPosition[2] + d[2]]])[0][0];
                            //@ts-ignore
                        } else if (Reflect.has(item, 'points') && item.points) {
                            // @ts-ignore
                            const tempPoints = positionsToLocalPositions({ originPosition: ov }, item.points)[0];
                            //@ts-ignore
                            item.points = localPositionsToPositions({ originPosition: ov }, tempPoints.map(item => [item[0] + d[0], item[1] + d[1], item[2] + d[2]]))[0];
                        }
                    });
                }));
                break;
            }
            if (Reflect.has(sceneObject, 'position')) {
                //@ts-ignore
                this.ad(bind([translationEditing, 'position'], [sceneObject, 'position']));
                break;
            }
            if (sceneObject instanceof ES3DTileset) {
                const czmES3DTileset = czmViewer.getCzmObject(sceneObject) as CzmES3DTileset;
                this.ad(bind([translationEditing, 'position'], [czmES3DTileset.czm3DTiles, 'position']));
                break;
            }
            //整体平移
            if (Reflect.has(sceneObject, 'points')) {
                //@ts-ignore
                if (sceneObject.points === undefined || sceneObject.points.length === 0) {
                    this.destroy();
                    break;
                };
                //@ts-ignore
                translationEditing.position = getMinMaxCorner(sceneObject.points).center;
                this.ad(translationEditing.positionChanged.disposableOn((v, ov) => {
                    if (v === undefined || ov === undefined ||
                        //@ts-ignore
                        sceneObject.points === undefined || sceneObject.points.length === 0) {
                        this.destroy();
                        return;
                    };
                    var d = positionsToLocalPositions({ originPosition: ov }, [v])[0][0];
                    //@ts-ignore
                    const tempPoints = positionsToLocalPositions({ originPosition: ov }, sceneObject.points)[0];
                    //@ts-ignore
                    sceneObject.points = localPositionsToPositions({ originPosition: ov }, tempPoints.map(item => [item[0] + d[0], item[1] + d[1], item[2] + d[2]]))[0];
                }));
                break;
            }
            this.supportEditing = false;
        } while (false);
    }
}